<template>
  <l-layout class="l-tab-page" v-show="!lr_loadPage" v-if="isInit" :top="queryHeight + 12">
    <template #left>
      <l-panel v-if="[2].includes(pageScheme.layoutType)" style="padding-right: 0">
        <template #title>
          {{ $t(pageScheme.left.title) }}
          <div
            class="tree-setting-btn"
            v-if="pageScheme.left.dataType == '2' && lr_hasPageAuth('classifysSetting', 'buttons')"
          >
            <el-tooltip effect="dark" content="分类管理" placement="top">
              <el-button @click="handleSettingClick" type="text" icon="el-icon-setting"></el-button>
            </el-tooltip>
          </div>
        </template>
        <el-tree :data="leftTreeData" :expand-on-click-node="false" @node-click="handleLeftNodeClick">
          <span class="lr-tree-node" slot-scope="{ node }">
            {{ $t(node.label) }}
          </span>
        </el-tree>
      </l-panel>
    </template>

    <template #top>
      <l-panel
        :style="{
          'padding-left': [2].includes(pageScheme.layoutType) ? 0 : 1,
          'padding-top': queryType != '1' ? '4px' : 1,
          'padding-bottom': 0,
        }"
        v-if="queryType != '1'"
      >
        <l-query
          :isKeywordSearch="isTableKeyword"
          :items="queryItems"
          :height.sync="queryHeight"
          :formData="queryData"
          @search="handleSearch"
        >
          <template v-for="queryComponent in queryComponents" v-slot:[queryComponent.prop]>
            <viewer-form-item
              v-model="queryData[queryComponent.prop]"
              :upCtrls="upCtrls"
              :formData="queryData"
              :data="queryComponent"
              :key="queryComponent.prop"
            ></viewer-form-item>
          </template>
        </l-query>
      </l-panel>
    </template>
    <l-panel
      :style="{
        'padding-left': [2].includes(pageScheme.layoutType) ? 0 : 1,
        'padding-top': queryType != '1' ? '4px' : 1,
      }"
    >
      <template v-if="(queryType == '1' && (queryComponents.length || isTableKeyword)) || queryType == '2'" #toolLeft>
        <l-query2
          v-if="queryType == '1'"
          :isKeywordSearch="isTableKeyword"
          :formData="queryData"
          :items="queryItems"
          @search="handleSearch"
        >
          <template v-for="queryComponent in queryComponents" v-slot:[queryComponent.prop]>
            <viewer-form-item
              v-model="queryData[queryComponent.prop]"
              :upCtrls="upCtrls"
              :formData="queryData"
              :data="queryComponent"
              :key="queryComponent.prop"
            ></viewer-form-item>
          </template>
        </l-query2>
        <div class="l-panel--item" v-else>
          <el-button
            style="margin-right: 8px"
            v-if="pageScheme.btns.findIndex((t) => t.id == 'Add') != -1 && lr_hasPageAuth('Add', 'buttons')"
            type="primary"
            size="mini"
            icon="el-icon-plus"
            @click="handleAdd()"
            >{{ $t("新增") }}</el-button
          >
          <l-excel-btns> </l-excel-btns>
          <!-- <el-button-group v-if="showExport">
            <el-button size="mini" icon="el-icon-download" @click="handleDownLoad">导出</el-button>
          </el-button-group> -->
        </div>
      </template>
      <template #toolRight>
        <l-tool-btns
          :hasTableSetting="hasTableSetting"
          @setting="handleSetting"
          :hasAdd="pageScheme.btns.findIndex((t) => t.id == 'Add') != -1 && queryType == '1'"
          @click="handleAdd()"
        >
          <l-excel-btns v-if="queryType == '1'"></l-excel-btns>
          <el-button-group v-if="showExport">
            <el-button size="mini" icon="el-icon-download" @click="handleDownLoad">导出</el-button>
          </el-button-group>
        </l-tool-btns>
      </template>
      <template #tabs>
        <div class="l-tabs-btns" style="margin: 8px 12px" v-if="tabsBtns.length">
          <el-radio-group v-model="tabsLabel" size="mini" @change="tabsChange">
            <el-radio-button v-for="tab in tabsBtns" :key="tab.label" :label="tab.label"></el-radio-button>
          </el-radio-group>
        </div>
      </template>

      <l-table
        ref="mainTable"
        :columns="lr_getPageColumns(tableColumns)"
        :dataSource="tableData"
        :row-key="`${mainTablePk}${formScheme.formType == 1 ? '' : mainTableIndex}`"
        :isPage="isTablePage"
        :tablePage.sync="tableCurrentPage"
        :pageTotal="tableTotal"
        @loadPageData="turnTablePage"
        @cellClick="cellClick"
        @handleColumnsCheck="handleColumnsCheck"
      >
        <template v-for="col in columnsByToLabel" v-slot:[col.prop]="scope">
          <el-button v-if="formChainColumsBytoLabelIncludes(col)" type="text" size="mini" :key="col.prop">{{
            scope.row[col.prop]
          }}</el-button>
          <l-value-to-label
            v-if="tableColumnsByToLabelIncludes(col)"
            :value="scope.row[col.prop]"
            :type="col.dataType"
            :code="col.dataCode"
            :valueKey="col.valueKey"
            :labelKey="col.labelKey"
            :options="col.options"
            :format="col.format"
            :setting="col.setting"
            :key="col.prop"
          ></l-value-to-label>
        </template>

        <l-table-btns :btns="tableBtns" @click="handleTableBtnClick"></l-table-btns>
      </l-table>
    </l-panel>

    <!--表单区域-->
    <custmer-form
      ref="CustmerForm"
      :isDialog="isDialog"
      :dialogHeight="dialogHeight"
      :dialogWidth="dialogWidth"
      :handleSave="handleSave"
      :handleOpenedForm="handleOpenedForm"
      :formInfo="formScheme.formInfo"
      :classifyCode="pageScheme.left.dataCode"
      :wfcode="wfcode"
      :name="name"
    ></custmer-form>

    <!--表单链区域-->
    <custmer-form
      ref="FormChain"
      :isDialog="isDialogChain"
      :dialogHeight="dialogHeightChain"
      :dialogWidth="dialogWidthChain"
      :handleSave="handleSaveChain"
      :handleOpenedForm="handleOpenedFormChain"
      :formInfo="formChainScheme.formInfo"
      :classifyCode="pageScheme.left.dataCode"
      :wfcode="wfcode"
      :name="name"
    ></custmer-form>
  </l-layout>
</template>

<script>
import queryString from "query-string";
import { mapGetters } from "vuex";
import CustmerForm from "./custmerForm.vue";

const api = window.$api.custmerForm.module;
const apiScheme = window.$api.custmerForm.scheme;
import { storage } from "@/core/util/util";

export default {
  components: {
    CustmerForm,
  },

  data() {
    return {
      lr_isPage: true,
      lr_isCustmerFormPage: true,
      name: "",
      moduleId: "",
      //表格tabs
      tabsBtns: [],
      tabsLabel: "",
      tabsParams: {},
      // 表格
      tableLoading: false,
      columns: [{ label: "", prop: "", minWidth: "1" }],
      tableData: [],
      tableTotal: 0,
      tablePageSize: 20,
      tableCurrentPage: 1,
      tableBtns: [],

      // 左侧树形
      leftTreeId: "",

      // 表单
      formSchemeId: "",
      formEditRow: null,
      formEdit: false,

      // 配置信息
      isInit: false,
      pageScheme: {},
      formScheme: {},

      // 主表数据
      mainTable: null,
      mainTableIndex: 0,
      // 组件映射
      componentMap: {},
      // 查询
      queryData: {},
      queryItems: [],
      queryComponents: [],
      queryHeight: 44,

      isWFlow: false,
      wfcode: "",

      isDetails: false,

      feildMaps: {},

      //表单链
      formChainScheme: {
        formInfo: {},
      },
      formChainEdit: false,
      formChainPrimaryKey: "",
      formChainPrimaryValue: "",
      feildFormChainMaps: {},
      //导出
      exportParams: {},
    };
  },

  computed: {
    ...mapGetters(["modules"]),
    columnsByToLabel() {
      return this.tableColumnsByToLabel.concat(this.formChainColumsBytoLabel);
    },
    hasTableSetting() {
      return this.pageScheme.table.hasTableSetting;
    },
    showExport() {
      return (
        this.pageScheme.btns.find((item) => item.prop == "Export") && this.lr_hasPageAuth("ExportExcel", "buttons")
      );
    },
    formChainColumsBytoLabel() {
      return this.tableColumns.filter(
        (item) =>
          item.formField &&
          item.formValue &&
          this.tableColumnsByToLabel.findIndex((col) => col.label == item.label) == -1
      );
    },
    leftTreeData() {
      const { dataType, dataCode, dataIdKey, dataPIdKey, dataValueKey, dataLabelKey, options, apiCode } =
        this.pageScheme.left;
      // 1 静态数据 2 数据字典 3 远端数据(数据源)

      switch (dataType) {
        case "1":
          return options;
        case "2":
          return this.lr_dataItemTree(this.lr_dataItem[dataCode]);
        case "3":
          return this.lr_DataSourceTree(
            this.lr_dataSourceData[dataCode],
            dataIdKey,
            dataPIdKey,
            dataValueKey,
            dataLabelKey
          );
        case "4":
          return this.lr_DataSourceTree(
            this.lr_apiDataSourceData[apiCode],
            dataIdKey,
            dataPIdKey,
            dataValueKey,
            dataLabelKey
          );
        default:
          return [];
      }
    },
    tableColumns() {
      const columns = [];
      this.pageScheme.table.columns.forEach((column) => {
        const columnComponent = this.componentMap[column.prop];

        if (columnComponent.field) {
          const enCode = `${columnComponent.field}${
            this.formScheme.formType == 0 ? this.formScheme.db.findIndex((t) => t.name == columnComponent.table) : ""
          }`;

          const col = {
            label: column.label,
            prop: enCode.toLowerCase(),
            formField: column.formField,
            formEdit: column.formEdit,
            formValue: column.formValue,
            align: column.align,
          };
          if (column.isMinWidth) {
            col.minWidth = column.width;
          } else {
            col.width = column.width;
          }

          const dataTypeRes = this.getComponentDataType(columnComponent);
          col.dataType = dataTypeRes.type;
          col.dataCode = dataTypeRes.code;
          col.valueKey = dataTypeRes.valueKey;
          col.labelKey = dataTypeRes.labelKey;
          col.options = dataTypeRes.options;
          col.format = dataTypeRes.format;
          if (["rate", "switch"].includes(columnComponent.type)) {
            col.setting = columnComponent;
          }

          columns.push(col);
        }
      });

      if (this.pageScheme.table.customColumns) {
        this.pageScheme.table.customColumns.forEach((column) => {
          const col = {
            label: column.label,
            prop: column.field,
            formField: column.formField,
            formEdit: column.formEdit,
            formValue: column.formValue,
            align: column.align,
          };

          if (column.isMinWidth) {
            col.minWidth = column.width;
          } else {
            col.width = column.width;
          }

          columns.push(col);
        });
      }

      if (columns.length > 0 && columns.findIndex((t) => t.minWidth > 0) == -1) {
        columns.forEach((col) => {
          col.minWidth = col.width;
          delete col.width;
        });
      }

      return columns;
    },
    tableColumnsByToLabel() {
      const tableColumnsByToLabel = this.lr_tableColumnsByToLabel(this.lr_getPageColumns(this.tableColumns));
      return tableColumnsByToLabel;
    },
    mainTablePk() {
      return this.formScheme.primaryKey;
    },
    isTablePage() {
      return this.pageScheme.table.isPage;
    },
    isTableKeyword() {
      return this.pageScheme.table.isKeyword;
    },
    queryType() {
      return this.pageScheme.queryType;
    },
    isDialogChain() {
      return this.formChainScheme.formInfo.openType != "2";
    },
    dialogHeightChain() {
      return this.formChainScheme.formInfo.dialogHeight || 600;
    },
    dialogWidthChain() {
      return this.formChainScheme.formInfo.dialogWidth || 800;
    },

    isDialog() {
      return this.formScheme.formInfo.openType != "2";
    },
    dialogHeight() {
      return this.formScheme.formInfo.dialogHeight || 600;
    },
    dialogWidth() {
      return this.formScheme.formInfo.dialogWidth || 800;
    },
    drawerWidth() {
      return this.formScheme.formInfo.drawerWidth || 600;
    },
    upCtrls() {
      const res = {};
      this.queryComponents.forEach((item) => {
        if (item.upCtrl) {
          res[item.upCtrl] = res[item.upCtrl] || [];
          res[item.upCtrl].push(item.prop);
        }
      });
      return res;
    },
    formType() {
      return this.formScheme.formType;
    },
  },
  watch: {
    $route: {
      handler() {
        this.init();
      },
      immediate: true,
    },
  },

  methods: {
    formChainColumsBytoLabelIncludes(col) {
      return this.formChainColumsBytoLabel.includes(col);
    },
    tableColumnsByToLabelIncludes(col) {
      return this.tableColumnsByToLabel.includes(col);
    },
    setColumnsHide() {
      const columnsCheck = storage.get(`hideColumns-${this.id}`);
      if (columnsCheck) {
        this.$refs.mainTable.setColumnsCheck(columnsCheck);
      }
    },
    handleColumnsCheck() {
      const columnsCheck = this.$refs.mainTable.getColumnsCheck();
      storage.set(`hideColumns-${this.id}`, columnsCheck);
    },
    handleSetting() {
      this.setColumnsHide();
      this.$refs.mainTable.openColumnsSetting();
    },
    async handleDownLoad() {
      const loading = this.$loading({
        lock: true,
        text: "文件导出中",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      const apiGet = this.formScheme.db.find((item) => item.apiType == 0);
      const api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiGet.f_Id}`));
      const exportParams = { ...this.$deepClone(this.exportParams), rows: 99999, page: 1 };
      let urlParams = queryString.stringify(exportParams);
      const params = {
        fileName: new Date().getTime() + "",
        dataUrl: `${api.f_Url}?${urlParams}`,
        isPage: true,
        isPost: false,
        reqData: "",
        columns: this.tableColumns.reduce((acc, cur) => {
          acc[cur.label] = cur.prop;
          return acc;
        }, {}),
      };
      //http://192.168.26.223:5000/excel/export/exportfile
      const url = await this.$awaitWraper(
        window.$axios({
          url: `${this.apiUrl}excel/export/exportfile`,
          method: "post",
          data: params,
        })
      );

      if (url) {
        // 导出成功
        this.$downFile(url);
      } else {
        this.$message({
          type: "error",
          message: "导出失败",
        });
      }

      loading.close();
    },

    setTabsParams(label) {
      const param = this.tabsBtns.find((item) => item.label === label);
      if (param) {
        this.tabsParams = { [param.paramName]: param.paramValue };
      }
    },
    tabsChange(label) {
      this.setTabsParams(label);
      this.loadTableData();
    },
    findFormDatatoValue(id, formData, feildMaps) {
      let result;
      if (Array.isArray(formData[id])) {
        result = formData[id].map((item) => {
          if (Object.prototype.toString.call(item) == "[object Object]") {
            return Object.keys(item).reduce((acc, crr) => {
              acc[feildMaps[crr]] = item[crr];
              return acc;
            }, {});
          }
          return item;
        });
      } else {
        result = formData[id];
      }
      return result;
    },
    toFormObject(arr, formData, feildMaps) {
      const result = {};
      const objectData = arr.filter((item) => item.type == "object");
      const arrayData = arr.filter((item) => item.type == "array");
      const basicData = arr.filter((item) => {
        return !item.parent && item.type == "basic";
      });

      objectData.forEach((item) => {
        const child = arr.filter((t) => t.parent == item.name);
        result[item.name] = child.reduce((acc, crr) => {
          acc[crr.name] = this.findFormDatatoValue(crr.value, formData, feildMaps);
          return acc;
        }, {});
      });

      arrayData.forEach((item) => {
        result[item.name] = this.findFormDatatoValue(item.value, formData, feildMaps);
      });

      basicData.forEach((item) => {
        result[item.name] = this.findFormDatatoValue(item.value, formData, feildMaps);
      });

      return result;
    },

    turnSavetoFormData(formData, apiSave) {
      const feildMaps = apiSave.reduce((arr, crr) => {
        if (crr.value) {
          arr[crr.value] = crr.name;
        }
        return arr;
      }, {});
      const result = this.toFormObject(apiSave, formData, feildMaps);
      return result;
    },
    async handleSaveChain(showLoading, hideLoading) {
      showLoading();
      if (await this.$refs.FormChain.validateForm()) {
        const formData = this.$refs.FormChain.getForm();
        const diffFormData = this.$refs.FormChain.getDiffFormData();
        const postData = {
          schemeId: this.formChainScheme.f_Id,
          isUpdate: this.formChainEdit,
          pkey: this.formChainPrimaryKey,
          pkeyValue: this.formChainEdit ? this.formChainPrimaryValue : "",
          data: JSON.stringify(formData),
          diffFormData: diffFormData,
        };

        //this.formScheme.formType==2 接口模式
        if (this.formChainScheme.formType == 2) {
          const apiPost = this.formChainScheme.db.find((item) => item.f_RequestMethod == "post");
          const apiPut = this.formChainScheme.db.find((item) => item.f_RequestMethod == "put");
          const apiSave = this.$deepClone(this.formChainScheme.output.apiSave);
          let params = this.turnSavetoFormData(formData, apiSave);
          let api;
          if (this.formChainEdit) {
            api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiPut.f_Id}`));
            await this.$awaitWraper(
              apiScheme.apiData(`${api.f_Url}/${this.formChainPrimaryValue}`, api.f_RequestMethod, params)
            );
          } else {
            api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiPost.f_Id}`));
            await this.$awaitWraper(apiScheme.apiData(api.f_Url, api.f_RequestMethod, params));
          }

          this.$message({
            type: "success",
            message: this.$t("保存成功!"),
          });
          this.$refs.FormChain.closeForm();
        } else {
          const res = await this.$awaitWraper(apiScheme.saveData(postData));
          if (res) {
            await this.$awaitWraper(this.$refs.FormChain.afterSaveEvent(res, this.formChainEdit));

            this.$message({
              type: "success",
              message: this.$t("保存成功!"),
            });
            this.$refs.FormChain.closeForm();
          }
        }
      }
      hideLoading();
    },
    cellClick(row, column) {
      if (this.formType == 2) {
        const col = this.tableColumns.find((item) => item.prop == column.property);

        if (col && col.formField && col.formValue) {
          //链表弹窗
          this.formChainPrimaryKey = col.formField;
          this.formChainPrimaryValue = row[col.formField];
          const formId = col.formValue;
          this.openFormChain(formId, col.label, col.formEdit);
        }
      }
    },
    async openFormChain(formId, label, formEdit) {
      //根据formId获取表单配置信息
      const data = await this.$awaitWraper(apiScheme.get(formId));
      if (data) {
        this.formChainScheme = JSON.parse(data.scheme.f_Scheme);

        this.formChainEdit = formEdit;
        const title = formEdit ? `${label}的编辑数据` : `${label}的详细数据`;

        this.$refs.FormChain.openForm(title, !formEdit);
      }
    },
    async handleOpenedFormChain(showLoading, hideLoading) {
      showLoading("加载数据中");
      const apiForm = this.formChainScheme.db.find((item) => item.apiType == 1);
      const api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiForm.f_Id}`));
      const res = await this.$awaitWraper(apiScheme.apiParams(`${api.f_Url}/${this.formChainPrimaryValue}`, "get"));
      await this.$refs.FormChain.init(this.turnApiDataForm(res));
      hideLoading();
    },
    // 页面初始化
    async init() {
      this.isInit = false;
      const module = this.modules.find((t) => t.f_UrlAddress == this.$route.query.src);
      await this.lr_loadPageAuth(); // 加载页面权限
      const res = await this.$awaitWraper(api.getScheme(module.f_UrlAddress));

      if (res && module.f_UrlAddress == this.$route.query.src) {
        this.id = res.entity.f_Id;

        this.moduleId = module.f_ModuleId;

        this.pageScheme = JSON.parse(res.entity.f_Scheme);
        this.formScheme = JSON.parse(res.formScheme.f_Scheme);
        // console.log("this.formScheme", this.formScheme);
        //console.log("this.pageScheme", this.pageScheme);
        // 表单模版id
        this.formSchemeId = res.formScheme.f_Id;
        // 主表
        this.mainTableIndex = this.formScheme.db.findIndex((t) => t.type == "main");
        this.mainTable = this.formScheme.db[this.mainTableIndex];
        // 设置映射值
        this.componentMap = this.getComponentMap(this.formScheme);

        // 设置查询
        this.setQueryData(this.pageScheme);
        // 设置按钮
        this.setBtns();

        // 设置左侧树形数据
        this.setTree();

        this.isInit = true;

        this.$nextTick(() => {
          // 加载列表数据
          this.loadTableData();
          //设置本地缓存表格列
          this.setColumnsHide();
        });
      }
    },
    getComponentMap(formScheme) {
      const componentMap = {};
      formScheme.formInfo.tabList.forEach((tab) => {
        tab.components.forEach((component) => {
          componentMap[component.prop] = component;
        });
      });
      return componentMap;
    },
    setQueryData(pageScheme) {
      const queryItems = [];
      const queryComponents = [];
      pageScheme.table.querys.forEach((item) => {
        const prop = item.prop;
        const queryComponent = this.$deepClone(this.componentMap[item.prop]);
        queryComponent.disabled = false;
        queryComponent.readonly = false;

        queryComponents.push(queryComponent);

        if (["switch"].includes(queryComponent.type)) {
          this.$set(
            this.queryData,
            queryComponent.prop,
            this.toValueType(queryComponent.valueType, queryComponent.default) ||
              this.toValueType(queryComponent.valueType, queryComponent.inactiveValue)
          );
        } else {
          this.$set(this.queryData, queryComponent.prop, undefined);
        }

        if (pageScheme.queryType == "1" && ["modifytime", "createtime", "datetime"].includes(queryComponent.type)) {
          queryItems.push({ label: queryComponent.label, prop: prop, span: 24 });
        } else {
          queryItems.push({ label: queryComponent.label, prop: prop, span: 24 });
        }

        if (["textarea", "password", "guid", "encode"].includes(queryComponent.type)) {
          queryComponent.type = "input";
        } else if (["datetime", "time"].includes(queryComponent.type)) {
          queryComponent.dateType = `${queryComponent.dateType}range`;
        } else if (["company"].includes(queryComponent.type)) {
          queryComponent.type = `companySelect`;
        } else if (["department"].includes(queryComponent.type)) {
          queryComponent.type = `departmentSelect`;
        } else if (["createuser", "modifyuser"].includes(queryComponent.type)) {
          queryComponent.type = `userSelect`;
        } else if (["createtime", "modifytime"].includes(queryComponent.type)) {
          queryComponent.type = `datetimerange`;
          queryComponent.dateType = `datetimerange`;
        }

        if (["userSelect", "departmentSelect", `companySelect`, "select"].includes(queryComponent.type)) {
          queryComponent.multiple = true;
        }
      });
      this.queryItems = queryItems;
      this.queryComponents = queryComponents;
    },
    toValueType(type, value) {
      if (!this.$validatenull(value) && !this.$validatenull(type)) {
        switch (type) {
          case "boolean":
            return value == "true";
          case "string":
            return value;
          case "number":
            return Number(value);
        }
      }
    },
    setBtns() {
      //console.log("this.pageScheme.btns", this.pageScheme.btns);
      const wfbtn = this.pageScheme.btns.find((t) => t.isWFlow && t.wFlowCode);
      if (wfbtn) {
        this.isWFlow = true;
        this.wfcode = wfbtn.wFlowCode;
      } else {
        this.isWFlow = false;
        this.wfcode = "";
      }
      //tabs切换
      const tabsBtn = this.pageScheme.btns.find((item) => item.prop == "Tabs");
      if (tabsBtn) {
        this.tabsBtns = tabsBtn.btns;
        if (tabsBtn.default) {
          this.tabsLabel = tabsBtn.default;
          this.setTabsParams(this.tabsLabel);
        }
      }

      this.tableBtns = this.pageScheme.btns.filter((t) => t.isRowBtn);
    },
    // 左侧树形数据
    setTree() {
      if (this.pageScheme.layoutType == 2) {
        const { dataType, dataCode, apiCode, apiUrl } = this.pageScheme.left;
        switch (dataType) {
          case "2":
            this.lr_loadDataItem(dataCode);
            break;
          case "3":
            this.lr_loadDataSourceData(dataCode);
            break;
          case "4":
            this.lr_loadApiDataSourceData(apiCode, apiUrl);
            break;
        }
      }
    },

    // 左侧树形
    handleLeftNodeClick(node) {
      this.leftTreeId = node.value;
      this.loadTableData();
    },
    setTreeNodeValue(queryData) {
      if (this.pageScheme.layoutType == 2) {
        queryData[this.pageScheme.left.colField] = this.leftTreeId || queryData[this.pageScheme.left.colField];
      }
    },
    handleSettingClick() {
      this.$refs.CustmerForm.openClassify();
    },

    // 表格
    // 获取组件数据类型
    getComponentDataType(compt) {
      const res = {};
      if (["radio", "checkbox", "select", "selectMultiple", "treeselect", "layerselect"].includes(compt.type)) {
        switch (compt.dataType) {
          case "1":
            res.type = "mydata";
            res.options = compt.options;
            break;
          case "2":
            res.type = "dataItem";
            res.code = compt.dataCode;
            break;
          case "3":
            res.type = "dataSource";
            res.code = compt.dataCode;
            res.valueKey = compt.dataValueKey;
            res.labelKey = compt.dataLabelKey;
            break;
        }
      } else if (["datetime", "createtime", "modifytime"].includes(compt.type)) {
        res.type = "datetime";
        res.format = compt.format || "yyyy-MM-dd HH:mm:ss";
      } else if (["upload"].includes(compt.type)) {
        res.type = "file";
      } else if (["uploadimg"].includes(compt.type)) {
        res.type = "img";
      } else if (["companySelect", "company"].includes(compt.type)) {
        res.type = "company";
      } else if (["departmentSelect", "department"].includes(compt.type)) {
        res.type = "department";
      } else if (["userSelect", "createuser", "modifyuser"].includes(compt.type)) {
        res.type = "user";
      } else if (["areaselect"].includes(compt.type)) {
        res.type = "areas";
      } else {
        res.type = compt.type;
      }
      return res;
    },

    // 表格按钮点击事件
    handleTableBtnClick(btn) {
      let handle = this["handle" + btn.type];
      handle && handle(btn.rowIndex, btn.row);
    },

    async loadTableData(isNotFirst) {
      if (!this.isInit) {
        return;
      }

      if (!isNotFirst) {
        this.tableCurrentPage = 1;
      }
      const loading = this.$loading({
        target: this.$refs.mainTable ? this.$refs.mainTable.$el : "document.body",
        lock: true,
        text: "加载数据中...",
        spinner: "el-icon-loading",
      });

      const queryParams = this.$deepClone(this.queryData);

      this.setTreeNodeValue(queryParams);

      const queryData = {
        queryJson: JSON.stringify(queryParams || {}),
      };

      if (this.pageScheme.table.sidx) {
        const sidxComponent = this.componentMap[this.pageScheme.table.sidx];
        queryData.sidx = `${sidxComponent.field}${
          this.formScheme.formType == 1 ? "" : this.formScheme.db.findIndex((t) => t.name == sidxComponent.table)
        }`;

        if (this.pageScheme.table.isDESC) {
          queryData.sidx += " DESC";
        }
      } else if (this.mainTablePk) {
        queryData.sidx = `${this.mainTablePk}${this.mainTableIndex}`;
      } else if (this.tableColumns.length > 0) {
        queryData.sidx = this.tableColumns[0].prop;
      }

      if (queryData.sidx == "0") {
        queryData.sidx = "";
      }

      if (window.$ldparam) {
        queryData.ldparam = window.$ldparam;
        window.$ldparam = undefined;
      }

      const apiGet = this.formScheme.db.find((item) => item.apiType == 0);
      const api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiGet.f_Id}`));

      if (this.isTablePage) {
        queryData.paginationInputDto = {
          rows: this.tablePageSize,
          page: this.tableCurrentPage,
          sidx: queryData.sidx,
        };
        this.exportParams = this.turnRequestParameters(queryParams, queryData);
        const params = this.formType == 2 ? this.exportParams : queryData;

        const data = await this.$awaitWraper(
          this.formType == 2
            ? apiScheme.apiParams(api.f_Url, api.f_RequestMethod, params)
            : apiScheme.getDataPage(this.moduleId, this.formSchemeId, params)
        );

        if (data != null) {
          this.tableData = this.formType == 2 ? this.tableDatatoLowerCase(data.rows) : data.rows; //Object.freeze(data.rows)
          this.tableTotal = data.records;
        } else {
          this.tableData = [];
          this.tableTotal = 0;
        }
      } else {
        this.exportParams = this.turnRequestParameters(queryParams, queryData);
        const params = this.formType == 2 ? this.exportParams : queryData;

        let tableData = await this.$awaitWraper(
          this.formType == 2
            ? apiScheme.apiParams(api.f_Url, api.f_RequestMethod, params)
            : apiScheme.getDataPage(this.moduleId, this.formSchemeId, params)
        );
        this.tableData = this.formType == 2 ? this.tableDatatoLowerCase(tableData) : tableData;
      }

      loading.close();

      //this.tableLoading = false
    },
    tableDatatoLowerCase(rows) {
      if (Array.isArray(rows)) {
        return rows.map((item) => {
          if (Object.prototype.toString.call(item) == "[object Object]") {
            return Object.keys(item).reduce((acc, cur) => {
              acc[cur.toLowerCase()] = item[cur];
              return acc;
            }, {});
          }
          return item;
        });
      }
      return rows;
    },
    turnRequestParameters(queryParams, queryData) {
      const { rows, page } = queryData.paginationInputDto;
      let params = {};
      if (Object.prototype.toString.call(queryParams) == "[object Object]") {
        params = Object.keys(queryParams).reduce((acc, cur) => {
          if (cur == "keyword") {
            acc[cur] = queryParams[cur];
            return acc;
          }
          acc[this.componentMap[cur].field] = queryParams[cur];
          return acc;
        }, {});
      }

      if (this.tabsBtns.length) {
        params = { ...params, ...this.tabsParams };
      }

      return this.isTablePage ? { ...params, rows, page } : params;
    },
    turnTablePage({ rows }) {
      this.tablePageSize = rows;
      this.loadTableData(true);
    },
    handleSearch(queryData) {
      this.queryData = queryData;
      this.loadTableData();
    },
    handleAdd() {
      if (this.isWFlow) {
        this.$refs.CustmerForm.openWf();
      } else {
        this.formEdit = false;
        this.$refs.CustmerForm.openForm("新增数据");
      }
    },
    handleEdit($index, row) {
      this.formEdit = true;
      this.formEditRow = row;
      this.$refs.CustmerForm.openForm("编辑数据");
    },
    handleDetails($index, row) {
      this.formEdit = true;
      this.formEditRow = row;
      this.$refs.CustmerForm.openForm("详细数据", true);
    },
    handleDelete($index, row) {
      this.$confirm(this.$t("此操作将永久删除该数据, 是否继续?"), this.$t("提示"), {
        confirmButtonText: this.$t("确定"),
        cancelButtonText: this.$t("取消"),
        type: "warning",
      })
        .then(async () => {
          if (this.formType == 2) {
            const apiDel = this.formScheme.db.find((item) => item.f_RequestMethod == "delete");
            const api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiDel.f_Id}`));
            await apiScheme.apiParams(`${api.f_Url}/${row[this.mainTablePk]}`, api.f_RequestMethod);
          } else {
            await apiScheme.removeData(this.formSchemeId, {
              key: this.mainTablePk,
              keyValue: row[`${this.mainTablePk.toLowerCase()}0`],
            });
          }
          this.tableData.splice($index, 1);
          this.tableTotal--;
          this.$message({
            type: "success",
            message: "删除成功!",
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },

    //表单发布，新增数据
    async handleSave(showLoading, hideLoading) {
      showLoading();
      if (await this.$refs.CustmerForm.validateForm()) {
        const formData = this.$refs.CustmerForm.getForm();
        const diffFormData = this.$refs.CustmerForm.getDiffFormData();
        const postData = {
          schemeId: this.formSchemeId,
          isUpdate: this.formEdit,
          pkey: this.mainTablePk,
          pkeyValue: this.formEdit ? this.formEditRow[`${this.mainTablePk}${this.mainTableIndex}`] : "",
          data: JSON.stringify(formData),
          diffFormData: diffFormData,
        };

        //this.formScheme.formType==2 接口模式
        if (this.formScheme.formType == 2) {
          const apiPost = this.formScheme.db.find((item) => item.f_RequestMethod == "post");
          const apiPut = this.formScheme.db.find((item) => item.f_RequestMethod == "put");
          const apiSave = this.$deepClone(this.formScheme.output.apiSave);
          let params = this.turnSavetoFormData(formData, apiSave);
          let api;
          if (this.formEdit) {
            api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiPut.f_Id}`));
            await this.$awaitWraper(
              apiScheme.apiData(`${api.f_Url}/${this.formEditRow[this.mainTablePk]}`, api.f_RequestMethod, params)
            );
          } else {
            api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiPost.f_Id}`));
            await this.$awaitWraper(apiScheme.apiData(`${api.f_Url}`, api.f_RequestMethod, params));
          }

          this.$message({
            type: "success",
            message: this.$t("保存成功!"),
          });
          this.$refs.CustmerForm.closeForm();
          this.loadTableData(true);
        } else {
          const res = await this.$awaitWraper(apiScheme.saveData(postData));
          if (res) {
            await this.$awaitWraper(this.$refs.CustmerForm.afterSaveEvent(res, this.formEdit));

            this.$message({
              type: "success",
              message: this.$t("保存成功!"),
            });
            this.$refs.CustmerForm.closeForm();
            this.loadTableData(true);
          }
        }
      }
      hideLoading();
    },

    turnToLowerCase(data) {
      let formData;
      if (Object.prototype.toString.call(data) == "[object Object]") {
        formData = {};
        Object.keys(data).forEach((key) => {
          formData[key.toLowerCase()] = data[key];
        });
      } else if (Array.isArray(data)) {
        formData = data.map((item) => {
          if (Object.prototype.toString.call(item) == "[object Object]") {
            let temp = {};
            Object.keys(item).forEach((key) => {
              temp[key.toLowerCase()] = item[key];
            });
            return temp;
          }
          return item;
        });
      } else {
        formData = data;
      }
      return formData;
    },
    turnApiDataForm(data) {
      let formdata = {};
      if (Object.prototype.toString.call(data) == "[object Object]") {
        const mainTable = Object.keys(data).filter((key) => {
          return !(Object.prototype.toString.call(data[key]) == "[object Object]" || Array.isArray(data[key]));
        });

        if (mainTable.length) {
          const mainData = mainTable.reduce((acc, crr) => {
            acc[crr.toLowerCase()] = data[crr];
            return acc;
          }, {});
          formdata = {
            root: [mainData],
          };
        }

        const childTable = Object.keys(data).filter((key) => {
          return Object.prototype.toString.call(data[key]) == "[object Object]" || Array.isArray(data[key]);
        });

        childTable.forEach((key) => {
          formdata[key.toLowerCase()] = [this.turnToLowerCase(data[key])];
        });
      }
      return formdata;
    },
    async handleOpenedForm(showLoading, hideLoading) {
      showLoading("加载数据中");
      if (this.formEdit) {
        if (this.formScheme.formType == 2) {
          const apiGet = this.formScheme.db.find((item) => item.apiType == 1);
          const api = await this.$awaitWraper(apiScheme.apiParams(`${this.apiUrl}data/datainterface/${apiGet.f_Id}`));
          const res = await this.$awaitWraper(
            apiScheme.request(`${api.f_Url}/${this.formEditRow[this.mainTablePk]}`, api.f_RequestMethod)
          );

          await this.$refs.CustmerForm.init(this.turnApiDataForm(res));
        } else if (this.formScheme.formType == 1) {
          let formdata = {};
          formdata[this.mainTable.name] = [this.formEditRow];
          const mainDataQuery = {};
          if (this.formScheme.db.length > 0) {
            this.formScheme.db.forEach((db) => {
              mainDataQuery[db.relationField] = this.formEditRow[db.relationField];
            });
            const res = await this.$awaitWraper(
              apiScheme.getViewData(this.formSchemeId, { mainData: JSON.stringify(mainDataQuery) })
            );
            formdata = {
              ...formdata,
              ...res,
            };
          }
          await this.$refs.CustmerForm.init(formdata);
        } else {
          const data = await this.$awaitWraper(
            apiScheme.getData(this.formSchemeId, {
              key: this.mainTablePk,
              keyValue: this.formEditRow[`${this.mainTablePk.toLowerCase()}0`],
            })
          );

          await this.$refs.CustmerForm.init(data);
        }
      } else {
        await this.$refs.CustmerForm.init();
      }
      hideLoading();
    },
  },
};
</script>
